home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
multiuser
/
src
/
library
/
log.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-23
|
22KB
|
512 lines
/************************************************************
* MultiUser - MultiUser Task/File Support System *
* --------------------------------------------------------- *
* Login Access Management *
* --------------------------------------------------------- *
* © Copyright 1993-1994 Geert Uytterhoeven *
* All Rights Reserved. *
************************************************************/
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <proto/reqtools.h>
#include <exec/execbase.h>
#include <exec/alerts.h>
#include <dos/dos.h>
#include <dos/var.h>
#include <dos/datetime.h>
#include <utility/tagitem.h>
#include <libraries/reqtools.h>
#include <string.h>
#include "Log.h"
#include "Misc.h"
#include "Config.h"
#include "Locale.h"
#include "LibHeader.h"
#include "UserInfo.h"
#include "Task.h"
#include "Server.h"
#include "Monitor.h"
/*
* Static Routines
*/
static void myfputs(BPTR file, STRPTR str);
static BOOL myfgets(BPTR file, STRPTR str, ULONG len);
static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li);
static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li);
static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li);
static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
int *retry, struct LocaleInfo *li);
static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li);
static BOOL CheckPassword(STRPTR uid);
/*
* Support Functions
*/
static void __inline myfputs(BPTR file, STRPTR str)
{
Write(file, str, strlen(str));
}
static BOOL __inline myfgets(BPTR file, STRPTR str, ULONG len)
{
LONG readlen;
readlen = Read(file, str, len);
if (readlen > 1) {
str[readlen-1] = '\0';
return(TRUE);
} else {
str[0] = '\0';
return(FALSE);
}
}
/*
* Logout and Restore the Previous User
*
* Public Library Function
*
* If there are no users left for the task, a login requester will
* appear.
*/
ULONG __asm __saveds muLogoutA(register __a0 struct TagItem *taglist)
{
struct muExtOwner *xuser;
ULONG user;
struct muPrivUserInfo *info;
char day[LEN_DATSTRING];
char date[LEN_DATSTRING];
char time[LEN_DATSTRING];
#define LASTLOGINSIZE (3*LEN_DATSTRING+2)
char lastlogin[LASTLOGINSIZE+1];
/* V39+: use lastlogin[LASTLOGINSIZE] */
char buffer[256];
BPTR file, dir, seglist;
struct DateTime dt;
struct FileInfoBlock *fib;
STRPTR args[6];
struct muTags tags;
struct Segment *seg;
BOOL neverloggedin = TRUE;
int i;
char *fmt;
BOOL nobody;
struct LocaleInfo li;
if (!InterpreteTagList(taglist, &tags))
return(muOWNER_NOBODY);
tags.UserID = tags.Password = NULL;
tags.NoLog = FALSE;
OpenLoc(&li);
do {
if (tags.Global)
nobody = !PopTaskLevelDetach(tags.Task);
else
nobody = !PopTaskDetach(tags.Task);
} while (tags.All && !nobody);
user = GetTaskOwner(tags.Task);
if (nobody && !tags.Quiet)
if (info = LoginRequest(&tags, FALSE, FALSE, &li)) {
PushTask(SysBase->ThisTask, &RootExtOwner);
xuser = muUserInfo2ExtOwner(info);
SetVar("Home", info->Pub.HomeDir, -1, GVF_LOCAL_ONLY);
if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) {
if (dir = Lock(info->Pub.HomeDir, ACCESS_READ)) {
if (Examine(dir, fib) && (fib->fib_DirEntryType > 0)) {
if (NameFromLock(dir, buffer, 256))
SetCurrentDirName(buffer);
dir = CurrentDir(dir);
}
UnLock(dir);
}
FreeDosObject(DOS_FIB, fib);
}
muFreeUserInfo(info);
if (file = Open(muLastLogin_FileName, MODE_OLDFILE)) {
if (FGets(file, lastlogin, LASTLOGINSIZE))
neverloggedin = FALSE;
Close(file);
}
dt.dat_Format = FORMAT_DOS;
dt.dat_Flags = NULL;
DateStamp(&dt.dat_Stamp);
dt.dat_StrDay = day;
dt.dat_StrDate = date;
dt.dat_StrTime = time;
DateToStr(&dt);
args[0] = day;
args[1] = date;
args[2] = time;
if (file = Open(muLastLogin_FileName, MODE_NEWFILE)) {
VFPrintf(file, "%s %s %s\n", (LONG *)args);
Close(file);
}
if (!neverloggedin) {
args[3] = lastlogin;
args[4] = "";
args[5] = "";
for (i = 0; lastlogin[i] && (lastlogin[i] != ' '); i++);
if (lastlogin[i]) {
lastlogin[i++] = '\0';
while (lastlogin[i] == ' ')
i++;
args[4] = &lastlogin[i];
while (lastlogin[i] && (lastlogin[i] != ' '))
i++;
if (lastlogin[i]) {
lastlogin[i++] = '\0';
while (lastlogin[i] == ' ')
i++;
args[5] = &lastlogin[i];
while (lastlogin[i] && (lastlogin[i] != ' ') &&
(lastlogin[i] != '\n'))
i++;
lastlogin[i] = '\0';
}
}
}
PopTask(SysBase->ThisTask);
if (neverloggedin)
fmt = GetLocS(&li,MSG_FIRSTLOGIN);
else
fmt = GetLocS(&li,MSG_LASTLOGIN);
if (tags.Graphical) {
if (muBase->Config.Flags & muCFGF_LastLoginReq)
rtEZRequestTags(fmt, GetLocS(&li,MSG_OK), NULL, args,
RTEZ_Flags, EZREQF_CENTERTEXT,
RT_PubScrName, tags.PubScrName,
RT_ReqPos, REQPOS_CENTERSCR,
RT_LockWindow, TRUE,
TAG_DONE);
} else {
FPuts(tags.Output, "\n");
VFPrintf(tags.Output, fmt, (LONG *)args);
FPuts(tags.Output, "\n");
Flush(tags.Output);
}
if (tags.Global)
PushTaskLevel(tags.Task, xuser);
else
PushTask(tags.Task, xuser);
if ((muBase->Config.Flags & muCFGF_Profile) &&
(dir = (BPTR)SendServerPacket(muSAction_ConfigDirLock, NULL,
NULL, NULL, NULL))) {
dir = CurrentDir(dir);
if (file = Lock(muProfile_FileName, ACCESS_READ)) {
Forbid();
if (seg = FindSegment("Execute", NULL, NULL))
seg->seg_UC++;
Permit();
if (seg)
seglist = seg->seg_Seg;
else
seglist = NewLoadSeg("C:Execute", NULL);
if (seglist) {
RunCommand(seglist, 4000, muProfile_FileName "\n",
strlen(muProfile_FileName "\n"));
if (!seg)
UnLoadSeg(seglist);
}
if (seg) {
Forbid();
seg->seg_UC--;
Permit();
}
UnLock(file);
}
UnLock(CurrentDir(dir));
}
user = muExtOwner2ULONG(xuser);
muFreeExtOwner(xuser);
} else
Die(NULL, AN_Unknown | AG_BadParm);
CloseLoc(&li);
return(user);
}
/*
* Login to the System and Add the User to the Task
*
* Public Library Function
*/
ULONG __asm __saveds muLoginA(register __a0 struct TagItem *taglist)
{
struct muExtOwner *xuser;
struct muPrivUserInfo *info;
struct muTags tags;
BOOL res;
struct LocaleInfo li;
if (!InterpreteTagList(taglist, &tags) || (tags.Password && !tags.UserID))
return(muOWNER_NOBODY);
xuser = GetTaskExtOwner(SysBase->ThisTask);
if (!tags.Own)
{ /* { by fpetzold */
OpenLoc(&li);
if (info = LoginRequest(&tags, TRUE, muGetRelationshipA(xuser, NULL, NULL) & muRelF_ROOT_UID, &li)) {
muFreeExtOwner(xuser);
xuser = muUserInfo2ExtOwner(info);
muFreeUserInfo(info);
} else {
muFreeExtOwner(xuser);
return(muOWNER_NOBODY);
}
CloseLoc(&li);
} /* } by fpetzold */
if (tags.Global)
res = PushTaskLevel(tags.Task, xuser);
else
res = PushTask(tags.Task, xuser);
muFreeExtOwner(xuser);
return(GetTaskOwner(tags.Task));
}
/*
* Request the User for a Login
*/
static struct muPrivUserInfo *LoginRequest(struct muTags *tags, BOOL failallowed, BOOL nopasswd, struct LocaleInfo *li)
{
BOOL ret;
char version[8];
char hostname[32];
char uidbuf[muUSERIDSIZE];
char pwdbuf[muPASSWORDSIZE];
STRPTR userid, password;
struct muPrivUserInfo *info = NULL;
int retry = 0, i;
if (GetVar("Kickstart", version, 8, GVF_GLOBAL_ONLY) == -1)
strcpy(version, "?");
if (GetVar("HostName", hostname, 32, GVF_GLOBAL_ONLY) == -1)
strcpy(hostname, "?");
else {
for (i = 0; hostname[i] && (hostname[i] != '.'); i++);
if (hostname[i] == '.')
hostname[i] = '\0';
}
do {
if (tags->UserID)
userid = tags->UserID;
else {
userid = uidbuf;
do {
memset(uidbuf, '\0', sizeof(uidbuf));
if (tags->Graphical)
ret = GetUserIDGUI(uidbuf, version, hostname,
tags->PubScrName, li);
else
ret = GetUserIDCon(uidbuf, version, hostname, tags->Input,
tags->Output, &retry, li);
if (!ret && failallowed)
return(NULL);
} while (!ret);
}
if (tags->Password)
password = tags->Password;
else {
password = pwdbuf;
memset(pwdbuf, '\0', sizeof(pwdbuf));
if (!nopasswd && CheckPassword(userid)) {
if (tags->Graphical)
ret = GetPasswordGUI(pwdbuf, tags->PubScrName, li);
else
ret = GetPasswordCon(pwdbuf, tags->Input, tags->Output, li);
if (!ret)
if (failallowed)
return(NULL);
else
password = NULL;
}
}
if (userid && password) {
info = (struct muPrivUserInfo *)SendServerPacket(muSAction_CheckUser, (LONG)userid,
(LONG)password, (LONG)nopasswd,
(LONG)tags->NoLog);
memset(pwdbuf, '\0', sizeof(pwdbuf));
if (!info)
if (failallowed)
return(NULL);
else if (tags->Graphical)
rtEZRequestTags(GetLocS(li,MSG_LOGINFAIL_GUI),
GetLocS(li,MSG_OK), NULL, NULL,
RTEZ_Flags, EZREQF_CENTERTEXT,
RT_PubScrName, tags->PubScrName,
RT_ReqPos, REQPOS_CENTERSCR,
RT_LockWindow, TRUE,
TAG_DONE);
else
myfputs(tags->Output, GetLocS(li,MSG_LOGINFAIL_CON));
}
} while (!info);
return(info);
}
/*
* Ask the User for his UserID (Graphical User Interface version)
*/
static BOOL GetUserIDGUI(STRPTR userid, STRPTR version, STRPTR hostname, STRPTR scrname, struct LocaleInfo *li)
{
STRPTR args[2];
args[0] = version;
args[1] = hostname;
return((BOOL)rtGetString(userid, muUSERIDSIZE-1, GetLocS(li,MSG_LOGINREQ_GUI),
NULL, RTGS_TextFmt, GetLocS(li,MSG_LOGINPROMPT_GUI),
RTGS_TextFmtArgs, args,
RTGS_Flags, GSREQF_CENTERTEXT,
RT_PubScrName, scrname,
RT_ReqPos, REQPOS_CENTERSCR,
RT_LockWindow, TRUE,
TAG_DONE));
}
/*
* Ask the User for his Password (Graphical User Interface version)
*/
static BOOL GetPasswordGUI(STRPTR password, STRPTR scrname, struct LocaleInfo *li)
{
return((BOOL)rtGetString(password, muPASSWORDSIZE-1,
GetLocS(li,MSG_LOGINREQ_GUI), NULL,
RTGS_TextFmt, GetLocS(li,MSG_PASSWDPROMPT_GUI),
RTGS_Invisible, TRUE,
RTGS_AllowEmpty, TRUE,
RTGS_Flags, GSREQF_CENTERTEXT,
RT_PubScrName, scrname,
RT_ReqPos, REQPOS_CENTERSCR,
RT_LockWindow, TRUE,
TAG_DONE));
}
/*
* Ask the User for his UserID (Standard Console I/O version)
*/
static BOOL GetUserIDCon(STRPTR userid, STRPTR version, STRPTR hostname, BPTR input, BPTR output,
int *retry, struct LocaleInfo *li)
{
STRPTR args[2];
BOOL ret;
args[0] = version;
args[1] = hostname;
if (!*retry) {
VFPrintf(output, GetLocS(li,MSG_LOGINREQ_CON), (LONG *)args);
Flush(output);
}
myfputs(output, GetLocS(li,MSG_LOGINPROMPT_CON));
myfputs(output," ");
ret = myfgets(input, userid, muUSERIDSIZE);
if (ret)
*retry = (*retry+1) % 4;
else
*retry = 0;
return(ret);
}
/*
* Ask the User for his Password (Standard Console I/O version)
*/
static BOOL GetPasswordCon(STRPTR password, BPTR input, BPTR output, struct LocaleInfo *li)
{
BOOL done;
ULONG len;
char buffer;
myfputs(output, GetLocS(li,MSG_PASSWDPROMPT_CON));
myfputs(output, "
");
done = FALSE;
len = 0;
SetMode(input, 1);
do {
Read(input, &buffer, 1);
switch(buffer) {
case '\b':
if (len) {
FPutC(output, '\b');
Flush(output);
len--;
}
break;
case '\n':
case '\r':
done = TRUE;
break;
default:
if ((len < muPASSWORDSIZE-1) && ((buffer & 0x7f) > 31)
&& (buffer != 127)) {
FPutC(output, ' ');
password[len++] = buffer;
} else
FPutC(output, 7);
Flush(output);
break;
}
} while (!done);
password[len] = '\0';
SetMode(input, 0);
myfputs(output, "\n");
return(TRUE);
}
/*
* Check whether a User has a Password or not
*/
static BOOL CheckPassword(STRPTR userid)
{
struct muPrivUserInfo *info;
BOOL pwd = TRUE;
if (info = muAllocUserInfo()) {
strncpy(info->Pub.UserID, userid, muUSERIDSIZE-1);
info->Pub.UserID[muUSERIDSIZE-1] = '\0';
if (SendServerPacket(muSAction_GetUserInfo, (LONG)info, muKeyType_UserID, NULL, NULL))
pwd = info->Password;
muFreeUserInfo(info);
}
return(pwd);
}